#include "ota_http_curl.h"
#include "curl/curl.h"
#include <stdlib.h>
#include "log.h"
#include <string.h>

/**
 * @brief 响应体写入回调函数
 * @param data 响应体数据
 * @param size 单个数据块的大小
 * @param nmemb 单个数据块的数量
 * @param clientp 客户端自定义数据
 * 
 * @note 把请求获得数据 装配在容器中 \
 * 计算整个数据的 大小 \
 * 把容器强转 为响应体结构体指针 \
 * 把容器中的data 开辟空间 大小为 size * nmemb + 1 加一个结束符 \
 * 把数据拷贝到容器中 \
 * 把数据大小写入容器len中 \
 * 返回size * nmemb
 */

static size_t ota_http_curl_write_cb(char *data,size_t size,size_t nmemb,void *clientp)
{
    // 把请求获得数据 装配在容器中 
    size_t size_all = size * nmemb;
    // 计算整个数据的 大小 把容器强转 为响应体结构体指针
    response_body_t *response_body = (response_body_t *)clientp;
    // 把容器中的data 开辟空间 大小为 size * nmemb + 1 加一个结束符
    response_body->data = malloc(size_all + 1);
    // 把数据拷贝到容器中 
    memcpy(response_body->data, data, size_all);
    response_body->data[size_all] = '\0';
    // 把数据大小写入容器len中 
    response_body->len = size_all + 1;
    // 返回size * nmemb
    return size_all;
}

/**
 * @brief 获取http响应体
 * @param url http请求地址
 * @return 响应体结构体指针
 * @note  创建一个空的响应体结构体指针，并初始化 \
 * 给curl设置参数 接受数据的回调函数 接受数据的容器 \
 * 执行curl \
 * 获取响应体 \
 * 释放资源curl \
 * 返回响应体结构体指针 
 */
response_body_t *ota_http_curl_get_response(char *url)
{
    // 创建一个空的响应体结构体指针，并初始化 
    CURL *curl = curl_easy_init();
    if (curl == NULL)
    {
        perror("curl_easy_init error");
        return NULL;
    }
    // 给curl设置参数 接受数据的回调函数 接受数据的容器 
    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ota_http_curl_write_cb);

    response_body_t *response_body = malloc(sizeof(response_body_t));
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)response_body);
    // 执行curl 
    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK)
    {
        perror("curl_easy_performG error");
        return NULL;
    }
    // 释放资源curl 
    curl_easy_cleanup(curl);
    // 返回响应体结构体指针 
    return response_body;
}

int ota_http_curl_download(char *url, char *file_path)
{
    // 创建一个空的响应体结构体指针，并初始化 
    CURL *curl = curl_easy_init();
    if (curl == NULL)
    {
        perror("curl_easy_init error");
        return -1;
    }
    // 给curl设置参数 接受数据的回调函数 接受数据的容器 
    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);

    FILE *file = fopen(file_path, "wb");
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)file);
    // 执行curl 
    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK)
    {
        perror("curl_easy_performD error");
        return -1;
    }
    // 释放资源curl 
    curl_easy_cleanup(curl);
    fclose(file);
    // 返回响应体结构体指针 
    return 0;
}